//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm;
using EntLibContrib.Resource.Properties;

namespace EntLibContrib.Resource.Configuration.Manageability
{
	/// <summary>
	/// Provides a default implementation for <see cref="AssemblyResourceProviderData"/> that
	/// splits policy overrides processing and WMI objects generation, performing approriate logging of 
	/// policy processing errors.
	/// </summary>
	public class AssemblyResourceProviderDataManageabilityProvider
		: ConfigurationElementManageabilityProviderBase<AssemblyResourceProviderData>
	{
		#region Constants
		/// <summary>
		/// The name of the resource assembly name property.
		/// </summary>
		public const string ResourceAssemblyNamePropertyName = "resourceAssemblyName";
		/// <summary>
		/// The name of the resource base name property.
		/// </summary>
		public const string ResourceBaseNamePropertyName = "resourceBaseName";
		#endregion

		#region Properties
		/// <summary>
		/// Gets the template for the name of the policy associated to the object.
		/// </summary>
		/// <value></value>
		/// <remarks>
		/// Elements that override
		/// <see cref="M:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationElementManageabilityProviderBase`1.AddAdministrativeTemplateDirectives(Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm.AdmContentBuilder,`0,Microsoft.Practices.EnterpriseLibrary.Common.Configuration.IConfigurationSource,System.String)"/>
		/// to avoid creating a policy must still override this property.
		/// </remarks>
		protected override string ElementPolicyNameTemplate
		{
			get
			{
				return null;	// no policy for these elements
			}
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initialize a new instance of the <see cref="AssemblyResourceProviderDataManageabilityProvider"/> class.
		/// </summary>
		/// <remarks>Default to ReadOnly</remarks>
		public AssemblyResourceProviderDataManageabilityProvider()
		{
			AssemblyResourceProviderDataWmiMapper.RegisterWmiTypes();
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Adds the ADM instructions that describe the policies that can be used to override the properties of
		/// a specific instance of the configuration element type managed by the receiver.
		/// </summary>
		/// <param name="contentBuilder">The <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm.AdmContentBuilder"/> to which the Adm instructions are to be appended.</param>
		/// <param name="configurationObject">The configuration object instance.</param>
		/// <param name="configurationSource">The configuration source from where to get additional configuration
		/// information, if necessary.</param>
		/// <param name="elementPolicyKeyName">The key for the element's policies.</param>
		/// <remarks>
		/// The default implementation for this method creates a policy, using
		/// <see cref="P:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationElementManageabilityProviderBase`1.ElementPolicyNameTemplate"/> to create the policy name and invoking
		/// <see cref="M:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationElementManageabilityProviderBase`1.AddElementAdministrativeTemplateParts(Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm.AdmContentBuilder,`0,Microsoft.Practices.EnterpriseLibrary.Common.Configuration.IConfigurationSource,System.String)"/>
		/// to add the policy parts.
		/// Subclasses managing objects that must not create a policy must override this method to just add the parts.
		/// </remarks>
		protected override void AddAdministrativeTemplateDirectives(AdmContentBuilder contentBuilder,
																																AssemblyResourceProviderData configurationObject,
																																IConfigurationSource configurationSource,
																																string elementPolicyKeyName)
		{
			// parts for providers are part of their resource manager's policies
			AddElementAdministrativeTemplateParts(contentBuilder,
																						configurationObject,
																						configurationSource,
																						elementPolicyKeyName);
		}

		/// <summary>
		/// Adds the ADM parts that represent the properties of
		/// a specific instance of the configuration element type managed by the receiver.
		/// </summary>
		/// <param name="contentBuilder">The <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm.AdmContentBuilder"/> to which the Adm instructions are to be appended.</param>
		/// <param name="configurationObject">The configuration object instance.</param>
		/// <param name="configurationSource">The configuration source from where to get additional configuration
		/// information, if necessary.</param>
		/// <param name="elementPolicyKeyName">The key for the element's policies.</param>
		/// <remarks>
		/// Subclasses managing objects that must not create a policy will likely need to include the elements' keys when creating the parts.
		/// </remarks>
		protected override void AddElementAdministrativeTemplateParts(AdmContentBuilder contentBuilder, 
																																	AssemblyResourceProviderData configurationObject, 
																																	IConfigurationSource configurationSource, 
																																	string elementPolicyKeyName)
		{
			contentBuilder.AddEditTextPart(InternalResources.AssemblyResourceProviderDataResourceAssemblyNamePartName,
																		elementPolicyKeyName,
																		ResourceAssemblyNamePropertyName,
																		configurationObject.ResourceAssemblyName,
																		1024,
																		true);

			contentBuilder.AddEditTextPart(InternalResources.AssemblyResourceProviderDataResourceBaseNamePartName,
																		elementPolicyKeyName,
																		ResourceBaseNamePropertyName,
																		configurationObject.ResourceBaseName,
																		255,
																		true);
		}

		/// <summary>
		/// Overrides the <paramref name="configurationObject"/>'s properties with the Group Policy values from the
		/// registry.
		/// </summary>
		/// <param name="configurationObject">The configuration object for instances that must be managed.</param>
		/// <param name="policyKey">The <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.IRegistryKey"/> which holds the Group Policy overrides for the
		/// configuration element.</param>
		/// <remarks>Subclasses implementing this method must retrieve all the override values from the registry
		/// before making modifications to the <paramref name="configurationObject"/> so any error retrieving
		/// the override values will cancel policy processing.</remarks>
		protected override void OverrideWithGroupPolicies(AssemblyResourceProviderData configurationObject, IRegistryKey policyKey)
		{
			string resourceAssemblyNameOverride = policyKey.GetStringValue(ResourceAssemblyNamePropertyName);
			string resourceBaseNameOverride = policyKey.GetStringValue(ResourceBaseNamePropertyName);

			configurationObject.ResourceAssemblyName = resourceAssemblyNameOverride;
			configurationObject.ResourceBaseName = resourceBaseNameOverride;
		}

		/// <summary>
		/// Creates the <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationSetting"/> instances that describe the
		/// configurationObject.
		/// </summary>
		/// <param name="configurationObject">The configuration object for instances that must be managed.</param>
		/// <param name="wmiSettings">A collection to where the generated WMI objects are to be added.</param>
		protected override void GenerateWmiObjects(AssemblyResourceProviderData configurationObject, ICollection<ConfigurationSetting> wmiSettings)
		{
			AssemblyResourceProviderDataWmiMapper.GenerateWmiObjects(configurationObject, wmiSettings);
		}
		#endregion
	}
}
